home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 21 / AACD 21.iso / AACD / Utilities / Ghostscript / src / gsdevmem.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-01-01  |  7.2 KB  |  233 lines

  1. /* Copyright (C) 1995, 1999 Aladdin Enterprises.  All rights reserved.
  2.   
  3.   This file is part of AFPL Ghostscript.
  4.   
  5.   AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author or
  6.   distributor accepts any responsibility for the consequences of using it, or
  7.   for whether it serves any particular purpose or works at all, unless he or
  8.   she says so in writing.  Refer to the Aladdin Free Public License (the
  9.   "License") for full details.
  10.   
  11.   Every copy of AFPL Ghostscript must include a copy of the License, normally
  12.   in a plain ASCII text file named PUBLIC.  The License grants you the right
  13.   to copy, modify and redistribute AFPL Ghostscript, but only under certain
  14.   conditions described in the License.  Among other things, the License
  15.   requires that the copyright notice and this notice be preserved on all
  16.   copies.
  17. */
  18.  
  19. /*$Id: gsdevmem.c,v 1.2 2000/09/19 19:00:27 lpd Exp $ */
  20. /* Memory device creation for Ghostscript library */
  21. #include "math_.h"        /* for fabs */
  22. #include "memory_.h"
  23. #include "gx.h"
  24. #include "gserrors.h"
  25. #include "gsdevice.h"        /* for prototypes */
  26. #include "gxarith.h"
  27. #include "gxdevice.h"
  28. #include "gxdevmem.h"
  29.  
  30. /* Make a memory (image) device. */
  31. /* If colors_size = -16, -24, or -32, this is a true-color device; */
  32. /* otherwise, colors_size is the size of the palette in bytes */
  33. /* (2^N for gray scale, 3*2^N for RGB color). */
  34. /* We separate device allocation and initialization at customer request. */
  35. int
  36. gs_initialize_wordimagedevice(gx_device_memory * new_dev, const gs_matrix * pmat,
  37.           uint width, uint height, const byte * colors, int colors_size,
  38.             bool word_oriented, bool page_device, gs_memory_t * mem)
  39. {
  40.     const gx_device_memory *proto_dev;
  41.     int palette_count = colors_size;
  42.     int num_components = 1;
  43.     int pcount;
  44.     int bits_per_pixel;
  45.     float x_pixels_per_unit, y_pixels_per_unit;
  46.     byte palette[256 * 3];
  47.     bool has_color;
  48.  
  49.     switch (colors_size) {
  50.     case 3 * 2:
  51.         palette_count = 2;
  52.         num_components = 3;
  53.     case 2:
  54.         bits_per_pixel = 1;
  55.         break;
  56.     case 3 * 4:
  57.         palette_count = 4;
  58.         num_components = 3;
  59.     case 4:
  60.         bits_per_pixel = 2;
  61.         break;
  62.     case 3 * 16:
  63.         palette_count = 16;
  64.         num_components = 3;
  65.     case 16:
  66.         bits_per_pixel = 4;
  67.         break;
  68.     case 3 * 256:
  69.         palette_count = 256;
  70.         num_components = 3;
  71.     case 256:
  72.         bits_per_pixel = 8;
  73.         break;
  74.     case -16:
  75.         bits_per_pixel = 16;
  76.         palette_count = 0;
  77.         break;
  78.     case -24:
  79.         bits_per_pixel = 24;
  80.         palette_count = 0;
  81.         break;
  82.     case -32:
  83.         bits_per_pixel = 32;
  84.         palette_count = 0;
  85.         break;
  86.     default:
  87.         return_error(gs_error_rangecheck);
  88.     }
  89.     proto_dev = (word_oriented ?
  90.          gdev_mem_word_device_for_bits(bits_per_pixel) :
  91.          gdev_mem_device_for_bits(bits_per_pixel));
  92.     if (proto_dev == 0)        /* no suitable device */
  93.     return_error(gs_error_rangecheck);
  94.     pcount = palette_count * 3;
  95.     /* Check to make sure the palette contains white and black, */
  96.     /* and, if it has any colors, the six primaries. */
  97.     if (bits_per_pixel <= 8) {
  98.     const byte *p;
  99.     byte *q;
  100.     int primary_mask = 0;
  101.     int i;
  102.  
  103.     has_color = false;
  104.     for (i = 0, p = colors, q = palette;
  105.          i < palette_count; i++, q += 3
  106.         ) {
  107.         int mask = 1;
  108.  
  109.         switch (num_components) {
  110.         case 1:    /* gray */
  111.             q[0] = q[1] = q[2] = *p++;
  112.             break;
  113.         default /* case 3 */ :        /* RGB */
  114.             q[0] = p[0], q[1] = p[1], q[2] = p[2];
  115.             p += 3;
  116.         }
  117. #define shift_mask(b,n)\
  118.   switch ( b ) { case 0xff: mask <<= n; case 0: break; default: mask = 0; }
  119.         shift_mask(q[0], 4);
  120.         shift_mask(q[1], 2);
  121.         shift_mask(q[2], 1);
  122. #undef shift_mask
  123.         primary_mask |= mask;
  124.         if (q[0] != q[1] || q[0] != q[2])
  125.         has_color = true;
  126.     }
  127.     switch (primary_mask) {
  128.         case 129:        /* just black and white */
  129.         if (has_color)    /* color but no primaries */
  130.             return_error(gs_error_rangecheck);
  131.         case 255:        /* full color */
  132.         break;
  133.         default:
  134.         return_error(gs_error_rangecheck);
  135.     }
  136.     } else
  137.     has_color = true;
  138.     /*
  139.      * The initial transformation matrix must map 1 user unit to
  140.      * 1/72".  Let W and H be the width and height in pixels, and
  141.      * assume the initial matrix is of the form [A 0 0 B X Y].
  142.      * Then the size of the image in user units is (W/|A|,H/|B|),
  143.      * hence the size in inches is ((W/|A|)/72,(H/|B|)/72), so
  144.      * the number of pixels per inch is
  145.      * (W/((W/|A|)/72),H/((H/|B|)/72)), or (|A|*72,|B|*72).
  146.      * Similarly, if the initial matrix is [0 A B 0 X Y] for a 90
  147.      * or 270 degree rotation, the size of the image in user
  148.      * units is (W/|B|,H/|A|), so the pixels per inch are
  149.      * (|B|*72,|A|*72).  We forbid non-orthogonal transformation
  150.      * matrices.
  151.      */
  152.     if (is_fzero2(pmat->xy, pmat->yx))
  153.     x_pixels_per_unit = pmat->xx, y_pixels_per_unit = pmat->yy;
  154.     else if (is_fzero2(pmat->xx, pmat->yy))
  155.     x_pixels_per_unit = pmat->yx, y_pixels_per_unit = pmat->xy;
  156.     else
  157.     return_error(gs_error_undefinedresult);
  158.     /* All checks done, initialize the device. */
  159.     if (bits_per_pixel == 1) {
  160.     /* Determine the polarity from the palette. */
  161.     gs_make_mem_device(new_dev, proto_dev, mem,
  162.                (page_device ? 1 : -1), 0);
  163.     /* This is somewhat bogus, but does the right thing */
  164.     /* in the only cases we care about. */
  165.     gdev_mem_mono_set_inverted(new_dev,
  166.                    (palette[0] | palette[1] | palette[2]) != 0);
  167.     } else {
  168.     byte *dev_palette = gs_alloc_string(mem, pcount,
  169.                         "gs_makeimagedevice(palette)");
  170.  
  171.     if (dev_palette == 0)
  172.         return_error(gs_error_VMerror);
  173.     gs_make_mem_device(new_dev, proto_dev, mem,
  174.                (page_device ? 1 : -1), 0);
  175.     new_dev->palette.size = pcount;
  176.     new_dev->palette.data = dev_palette;
  177.     memcpy(dev_palette, palette, pcount);
  178.     if (!has_color) {
  179.         new_dev->color_info.num_components = 1;
  180.         new_dev->color_info.max_color = 0;
  181.         new_dev->color_info.dither_colors = 0;
  182.     }
  183.     }
  184.     new_dev->initial_matrix = *pmat;
  185.     new_dev->MarginsHWResolution[0] = new_dev->HWResolution[0] =
  186.     fabs(x_pixels_per_unit) * 72;
  187.     new_dev->MarginsHWResolution[1] = new_dev->HWResolution[1] =
  188.     fabs(y_pixels_per_unit) * 72;
  189.     gx_device_set_width_height((gx_device *) new_dev, width, height);
  190.     /* Set the ImagingBBox so we get a correct clipping region. */
  191.     {
  192.     gs_rect bbox;
  193.  
  194.     bbox.p.x = 0;
  195.     bbox.p.y = 0;
  196.     bbox.q.x = width;
  197.     bbox.q.y = height;
  198.     gs_bbox_transform_inverse(&bbox, pmat, &bbox);
  199.     new_dev->ImagingBBox[0] = bbox.p.x;
  200.     new_dev->ImagingBBox[1] = bbox.p.y;
  201.     new_dev->ImagingBBox[2] = bbox.q.x;
  202.     new_dev->ImagingBBox[3] = bbox.q.y;
  203.     new_dev->ImagingBBox_set = true;
  204.     }
  205.     /* The bitmap will be allocated when the device is opened. */
  206.     new_dev->is_open = false;
  207.     new_dev->bitmap_memory = mem;
  208.     return 0;
  209. }
  210.  
  211. int
  212. gs_makewordimagedevice(gx_device ** pnew_dev, const gs_matrix * pmat,
  213.            uint width, uint height, const byte * colors, int num_colors,
  214.             bool word_oriented, bool page_device, gs_memory_t * mem)
  215. {
  216.     int code;
  217.     gx_device_memory *pnew =
  218.     gs_alloc_struct(mem, gx_device_memory, &st_device_memory,
  219.             "gs_makeimagedevice(device)");
  220.  
  221.     if (pnew == 0)
  222.     return_error(gs_error_VMerror);
  223.     code = gs_initialize_wordimagedevice(pnew, pmat, width, height,
  224.                      colors, num_colors, word_oriented,
  225.                      page_device, mem);
  226.     if (code < 0) {
  227.     gs_free_object(mem, pnew, "gs_makeimagedevice(device)");
  228.     return code;
  229.     }
  230.     *pnew_dev = (gx_device *) pnew;
  231.     return 0;
  232. }
  233.